<template>
  <div class="cesium-draw">
    <div id="cesium-drawer" />

    <a-dropdown>
      <a class="ant-dropdown-link tools" @click.prevent>
        画{{ drawingModeText }}
        <DownOutlined />
      </a>

      <template #overlay>
        <a-menu @click="handleMenuClick">
          <a-menu-item v-for="(e, index) in types" :key="e.key">{{ e.text }}</a-menu-item>
        </a-menu>
      </template>
    </a-dropdown>

    <!-- <layer-control :viewer="viewer" /> -->

    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>
  </div>
</template>

<script>
//参考填挖方： https://www.cnblogs.com/giserhome/p/11374089.html
// import cesiumEarth from '../components/cesium-tdt.vue';
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, onMounted, h } from 'vue';
import * as Cesium from '@cesium/Source/Cesium.js';
import MousePosition from './utils/mousePosition.js';
// import LayerControl from "./components/LayerControl";
import { arcGisMapServerImageryProviderCreator, arcGisMapServerStreetMapImageryProviderCreator } from '@lib/provider/arcgis.js';
// import {
//   imgTileServiceImageryProviderCreator,
//   vecTileServiceImageryProviderCreator,
//   terTileServiceImageryProviderCreator,
//   ciaTileServiceImageryProviderCreator,
//   img_tdt_yx,
//   img_tdt_sl,
//   img_tdt_dx,
//   imageryProvider
// } from '@lib/provider/tdt.js';
// const imageryProviderViewModels = [img_tdt_yx(), img_tdt_dx(), img_tdt_sl()];

export default defineComponent({
  components: { DownOutlined, EditOutlined,  },
  setup() {
    return {
      // viewer: null
    };
  },
  data() {
    return {
      viewer: null,
      drawingMode: 'line',
      types: [
        {
          text: '线',
          key: 'line'
        },
        {
          text: '多边形',
          key: 'polygon'
        },
        {
          text: '圆',
          key: 'circle'
        },
        {
          text: '矩形',
          key: 'rectangle'
        }
      ],
      nowPostion: {},
      // nowCartesian3: undefined,
      floatingPoint: undefined,
      activeShape: undefined,
      activeShapePoints: []
    };
  },
  computed: {
    drawingModeText() {
      const { drawingMode, types } = this;
      return types.filter(e => e.key === drawingMode)[0].text;
    },
  },
  mounted() {
    this.initViewer();
  },
  beforeUnmount(){
    if(this.viewer){
      this.viewer.destroy()
    }
  },
  methods: {
    handleMenuClick(e) {
      this.terminateShape();
      console.log(e);
      this.drawingMode = e.key;
    },
    onMouseMove(event) {
      const { viewer, floatingPoint, activeShapePoints } = this;
      var newPosition = viewer.scene.pickPosition(event.endPosition);
      if (Cesium.defined(floatingPoint)) {
        if (Cesium.defined(newPosition)) {
          floatingPoint.position.setValue(newPosition);
          activeShapePoints.pop();
          activeShapePoints.push(newPosition);
        }
      }
    },
    onMouseClick(event) {
      let vm = this;
      const { drawShape, viewer, drawingMode, activeShape, activeShapePoints } = this;

      //绘制点
      function createPoint(worldPosition) {
        var point = viewer.entities.add({
          position: worldPosition,
          point: {
            color: Cesium.Color.WHITE,
            pixelSize: 5,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
          }
        });
        return point;
      }

      // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that
      // we get the correct point when mousing over terrain.
      var earthPosition = viewer.scene.pickPosition(event.position);
      // `earthPosition` will be undefined if our mouse is not over the globe.
      if (Cesium.defined(earthPosition)) {
        if (activeShapePoints.length === 0) {
          vm.floatingPoint = createPoint(earthPosition);
          activeShapePoints.push(earthPosition);
          var dynamicPositions = new Cesium.CallbackProperty(function() {
            if (drawingMode === 'polygon') {
              return new Cesium.PolygonHierarchy(activeShapePoints);
            }
            return activeShapePoints;
          }, false);
          vm.activeShape = drawShape(dynamicPositions); //绘制动态图
        }
        activeShapePoints.push(earthPosition);
        createPoint(earthPosition);
      }
    },
    terminateShape() {
      let vm = this;
      const { drawShape, viewer, floatingPoint, activeShape, activeShapePoints } = this;

      activeShapePoints.pop(); //去除最后一个动态点
      if (activeShapePoints.length) {
        drawShape(activeShapePoints); //绘制最终图
      }
      viewer.entities.remove(floatingPoint); //去除动态点图形（当前鼠标点）
      viewer.entities.remove(activeShape); //去除动态图形
      vm.floatingPoint = undefined;
      vm.activeShape = undefined;
      vm.activeShapePoints = [];
    },
    initEvents() {
      let vm = this;
      const { viewer } = this;

      //双击鼠标左键清除默认事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

      var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);

      //鼠标左键
      handler.setInputAction(vm.onMouseClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      //鼠标移动
      handler.setInputAction(vm.onMouseMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      handler.setInputAction(vm.terminateShape, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    },
    //绘制图形
    //初始化为线
    drawShape(positionData) {
      let vm = this;
      const { viewer, drawingMode, floatingPoint, activeShape, activeShapePoints } = this;
      var shape;
      if (drawingMode === 'line') {
        shape = viewer.entities.add({
          polyline: {
            positions: positionData,
            clampToGround: true,
            width: 3
          }
        });
      } else if (drawingMode === 'polygon') {
        shape = viewer.entities.add({
          polygon: {
            hierarchy: positionData,
            material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7))
          }
        });
      } else if (drawingMode === 'circle') {
        //当positionData为数组时绘制最终图，如果为function则绘制动态图
        var value = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
        //var start = activeShapePoints[0];
        //var end = activeShapePoints[activeShapePoints.length - 1];
        //var r = Math.sqrt(Math.pow(start.x - end.x, 2) + Math.pow(start.y - end.y, 2));
        //r = r ? r : r + 1;
        shape = viewer.entities.add({
          position: activeShapePoints[0],
          name: 'Blue translucent, rotated, and extruded ellipse with outline',
          type: 'Selection tool',
          ellipse: {
            semiMinorAxis: new Cesium.CallbackProperty(function() {
              //半径 两点间距离
              var r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x, 2) + Math.pow(value[0].y - value[value.length - 1].y, 2));
              return r ? r : r + 1;
            }, false),
            semiMajorAxis: new Cesium.CallbackProperty(function() {
              var r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x, 2) + Math.pow(value[0].y - value[value.length - 1].y, 2));
              return r ? r : r + 1;
            }, false),
            material: Cesium.Color.BLUE.withAlpha(0.5),
            outline: true
          }
        });
      } else if (drawingMode === 'rectangle') {
        //当positionData为数组时绘制最终图，如果为function则绘制动态图
        var arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
        shape = viewer.entities.add({
          name: 'Blue translucent, rotated, and extruded ellipse with outline',
          rectangle: {
            coordinates: new Cesium.CallbackProperty(function() {
              var obj = Cesium.Rectangle.fromCartesianArray(arr);
              //if(obj.west==obj.east){ obj.east+=0.000001};
              //if(obj.south==obj.north){obj.north+=0.000001};
              return obj;
            }, false),
            material: Cesium.Color.RED.withAlpha(0.5)
          }
        });
      }
      return shape;
    },
    initViewer() {
      let vm = this;
      // Grant CesiumJS access to your ion assets
      // Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0MDRkNWFkMi1jMGNkLTQyZmQtYTRmNi0yYmUyZTgxMTAyMTIiLCJpZCI6NTE0ODgsImlhdCI6MTYxODE3NzAyMH0.0Cv1f5WY2p_vMWoUF7zRPDRFSEsMWiRlnpIXhmMqDqE';
      var viewer = new Cesium.Viewer('cesium-drawer', {
        animation: false,
        // baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        timeline: false,
        imageryProvider: arcGisMapServerImageryProviderCreator(),
        selectionIndicator: false,
        infoBox: false,
        // 注释时相当于使用默认地形，解开注释相当于使用全球地形
        terrainProvider: Cesium.createWorldTerrain()
      });
      this.viewer = viewer;

      viewer.scene.globe.depthTestAgainstTerrain = true;

      // Zoom in to an area with mountains
      viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), new Cesium.Cartesian3(5000.0, 5000.0, 5000.0));
      viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

      this.initEvents();

      new MousePosition(viewer,(pos)=>{
        vm.nowPostion = pos;
      })
    }
  }
});
</script>

<style scoped lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;

  .tools {
    position: absolute;
    top: 57px;
    left: 7px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.6;
    transition: all 500ms;
    &:hover {
      opacity: 0.8;
    }
  }

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    :deep(.cesium-viewer-bottom) {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    left: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}
</style>
